package com.whmall.service.crm.module.company.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.whmall.common.enumeration.YesNoEnum;
import com.whmall.component.entity.dto.CompanyUserInvoiceDTO;
import com.whmall.component.entity.dto.OperatorReqDTO;
import com.whmall.component.entity.dto.PageReqDTO;
import com.whmall.component.entity.dto.PageRspDTO;
import com.whmall.component.enumeration.OperatorTypeEnum;
import com.whmall.component.util.FieldUtils;
import com.whmall.service.crm.entity.dto.company.CompanyUserInvoiceAddReqDTO;
import com.whmall.service.crm.entity.dto.company.CompanyUserInvoiceQueryReqDTO;
import com.whmall.service.crm.entity.dto.company.CompanyUserInvoiceUpdateReqDTO;
import com.whmall.service.crm.module.company.dao.CompanyUserInvoiceMapper;
import com.whmall.service.crm.module.company.entity.CompanyUserInvoiceDO;
import com.whmall.service.crm.module.company.entity.qo.CompanyUserInvoiceQO;
import com.whmall.service.crm.module.company.service.CompanyUserInvoiceService;
import com.whmall.service.crm.module.companyuser.dao.CompanyUserMapper;
import com.whmall.service.crm.module.companyuser.entity.CompanyUserDO;
import com.whmall.service.crm.util.PageDTOHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CompanyUserInvoiceServiceImpl implements CompanyUserInvoiceService {

    @Autowired
    private CompanyUserInvoiceMapper companyUserInvoiceMapper;

    @Autowired
    private CompanyUserMapper companyUserMapper;

    @Override
    public List<CompanyUserInvoiceDTO> list(CompanyUserInvoiceQueryReqDTO queryReqDTO) {
        CompanyUserInvoiceQO qo = new CompanyUserInvoiceQO();
        BeanUtils.copyProperties(queryReqDTO, qo);
        qo.setDeleted(0);
        qo.setOrderBy("default_invoice");
        return companyUserInvoiceMapper.listBy(qo).stream()
                .map(e -> {
                    CompanyUserInvoiceDTO rspDTO = new CompanyUserInvoiceDTO();
                    BeanUtils.copyProperties(e, rspDTO);
                    rspDTO.setDefaultInvoice(FieldUtils.unwrapDefault(rspDTO.getDefaultInvoice()));
                    return rspDTO;
                }).collect(Collectors.toList());
    }

    @SuppressWarnings("unchecked")
    @Override
    public PageRspDTO<CompanyUserInvoiceDTO> list(PageReqDTO pageReqDTO, CompanyUserInvoiceQueryReqDTO reqDTO) {
        CompanyUserInvoiceQO qo = new CompanyUserInvoiceQO();
        BeanUtils.copyProperties(reqDTO, qo);
        qo.setDeleted(0);
        qo.setOrderBy("default_invoice");
        PageDTOHelper.startPage(pageReqDTO);
        List<CompanyUserInvoiceDO> invoices = companyUserInvoiceMapper.listBy(qo);
        PageRspDTO pageRspDTO = PageDTOHelper.toPageDTO(invoices);
        List<CompanyUserInvoiceDTO> rspDTOs = invoices.stream()
                .map(e -> {
                    CompanyUserInvoiceDTO rspDTO = new CompanyUserInvoiceDTO();
                    BeanUtils.copyProperties(e, rspDTO);
                    rspDTO.setDefaultInvoice(FieldUtils.unwrapDefault(rspDTO.getDefaultInvoice()));
                    return rspDTO;
                }).collect(Collectors.toList());
        pageRspDTO.setRecords(rspDTOs);
        return pageRspDTO;
    }

    @Transactional
    @Override
    public Long add(CompanyUserInvoiceAddReqDTO reqDTO) {
        CompanyUserDO user = companyUserMapper.getById(reqDTO.getUserId());
        CompanyUserInvoiceDO invoice = new CompanyUserInvoiceDO();
        BeanUtils.copyProperties(reqDTO, invoice);
        invoice.setCompanyId(user.getCompanyId());
        if(Integer.valueOf(1).equals(invoice.getIsEnabled())){
            invoice.setEnableId(reqDTO.getOperator().getOperatorId());
            invoice.setEnableType(reqDTO.getOperator().getOperatorType().getValue());
            invoice.setEnableTime(new Date());
        }
        Long invoiceCount = companyUserInvoiceMapper.selectCount(new LambdaQueryWrapper<CompanyUserInvoiceDO>()
                .eq(CompanyUserInvoiceDO::getDeleted, 0)
                .eq(CompanyUserInvoiceDO::getUserId, user.getId()));
        if (invoiceCount == 0) {
            invoice.setDefaultInvoice(1);
        }
        invoice.setCreateId(reqDTO.getOperator().getOperatorId());
        invoice.setCreateType(reqDTO.getOperator().getOperatorType().getValue());
        //处理默认发票
        processDefault(invoice, reqDTO.getOperator());
        //保存
        try {
            companyUserInvoiceMapper.insertSelective(invoice);
        } catch (DuplicateKeyException e) {
            throw new IllegalArgumentException("已存在该发票类型、税务号、开户行、银行账号的发票，不能重复");
        }
        return invoice.getId();
    }

    @Transactional
    @Override
    public void update(CompanyUserInvoiceUpdateReqDTO reqDTO) {
        CompanyUserDO user = companyUserMapper.getById(reqDTO.getUserId());
        CompanyUserInvoiceDO invoice = new CompanyUserInvoiceDO();
        BeanUtils.copyProperties(reqDTO, invoice);
        invoice.setCompanyId(user.getCompanyId());
        Date now = new Date();
        if(Integer.valueOf(1).equals(invoice.getIsEnabled())){
            invoice.setEnableId(reqDTO.getOperator().getOperatorId());
            invoice.setEnableType(reqDTO.getOperator().getOperatorType().getValue());
            invoice.setEnableTime(now);
        }
        invoice.setUpdateId(reqDTO.getOperator().getOperatorId());
        invoice.setUpdateType(reqDTO.getOperator().getOperatorType().getValue());
        invoice.setUpdateTime(now);
        //处理默认发票
        processDefault(invoice, reqDTO.getOperator());
        //保存
        try {
            companyUserInvoiceMapper.updateByIdSelective(invoice);
        } catch (DuplicateKeyException e) {
            throw new IllegalArgumentException("已存在该发票类型、税务号、开户行、银行账号的发票，不能重复");
        }
    }

    @Transactional
    @Override
    public void remove(Long id, OperatorReqDTO operator) {
        CompanyUserInvoiceDO invoice = CompanyUserInvoiceDO.builder()
                .id(id)
                .deleted((int)(System.currentTimeMillis()/1000))
                .updateId(operator.getOperatorId())
                .updateType(operator.getOperatorType().getValue())
                .updateTime(new Date())
                .build();
        int count = companyUserInvoiceMapper.updateByIdSelective(invoice);
        if(count != 1) {
            throw new IllegalArgumentException("未找到发票信息");
        }

    }

    @Transactional
    @Override
    public void setDefault(Long id, Long employeeId) {
        CompanyUserInvoiceDO invoice = companyUserInvoiceMapper.selectById(id);
        invoice.setDefaultInvoice(invoice.getDefaultInvoice() == YesNoEnum.YES.getCode() ? (int)(System.currentTimeMillis()/1000) : YesNoEnum.YES.getCode());
        //处理默认发票
        processDefault(invoice, OperatorReqDTO.builder().operatorType(OperatorTypeEnum.EMPLOYEE).operatorId(employeeId).build());
        //保存
        invoice = CompanyUserInvoiceDO.builder()
                .id(invoice.getId())
                .defaultInvoice(invoice.getDefaultInvoice())
                .updateId(employeeId)
                .updateType(OperatorTypeEnum.EMPLOYEE.getValue())
                .updateTime(new Date())
                .build();
        companyUserInvoiceMapper.updateByIdSelective(invoice);
    }

    /**
     * 处理默认发票
     * @param invoice
     * @param operator
     */
    private void processDefault(CompanyUserInvoiceDO invoice, OperatorReqDTO operator) {
        if(invoice.getDefaultInvoice() != 1) {//非默认
            if(invoice.getId() != null){
                CompanyUserInvoiceDO oldInvoice = companyUserInvoiceMapper.selectById(invoice.getId());
                //如果原本就是非默认的，是否默认字段的值就不变化，有利于排序
                invoice.setDefaultInvoice(oldInvoice.getDefaultInvoice() != 1 ?
                        oldInvoice.getDefaultInvoice() : (int)(System.currentTimeMillis()/1000));
            } else {
                invoice.setDefaultInvoice((int)(System.currentTimeMillis()/1000));
            }
        } else {//默认
            //把原有默认记录设置为非默认
            CompanyUserInvoiceQO qo = CompanyUserInvoiceQO.builder()
                    .companyId(invoice.getCompanyId())
                    .userId(invoice.getUserId())
                    .defaultInvoice(1)
                    .build();
            List<CompanyUserInvoiceDO> invoices = companyUserInvoiceMapper.listBy(qo);
            if(invoices.size() > 0) {
                //通过唯一索引查询，只会有1条
                CompanyUserInvoiceDO invoiceUpdate = CompanyUserInvoiceDO.builder()
                        .id(invoices.get(0).getId())
                        .defaultInvoice((int)(System.currentTimeMillis()/1000))
                        .updateId(operator.getOperatorId())
                        .updateType(operator.getOperatorType().getValue())
                        .updateTime(new Date())
                        .build();
                companyUserInvoiceMapper.updateByIdSelective(invoiceUpdate);
            }
        }
    }

    @Override
    public CompanyUserInvoiceDTO getByCompanyId(Long companyId) {
        CompanyUserInvoiceDO companyUserInvoiceDO = companyUserInvoiceMapper.getByCompanyId(companyId);
        if (companyUserInvoiceDO == null){
            return null;
        }
        CompanyUserInvoiceDTO rspDTO = new CompanyUserInvoiceDTO();
        BeanUtils.copyProperties(companyUserInvoiceDO, rspDTO);
        rspDTO.setDefaultInvoice(FieldUtils.unwrapDefault(rspDTO.getDefaultInvoice()));
        return rspDTO;
    }
}
